<template>
    <el-row>
        <el-col :span="0" class="scrollDiv" style="height:calc(100vh - 90px);overflow-y: scroll">
        <!--<CommonPmsCategory @queryData= "queryData"/>-->
        </el-col>
        <el-col :span="23" style="display: flex;flex-flow:column;justify-content: flex-start;align-items: center" >
            <div style="height:50px;display: flex;justify-content: space-between;align-items: center">
                <el-form inline >
                <el-form-item>
                <el-input style="width:80px" v-model= armynum type=number min=1 placeholder="敌人数量" />
                </el-form-item>
                <el-form-item>
                    <el-button type="primary" plain  activity @click="startGame">开始游戏</el-button>
                </el-form-item>
                <el-form-item>
                    <el-button type="primary" plain  @click="stopGame">结束游戏</el-button>
                </el-form-item>
                </el-form>
            </div>
            <div class="tankArea" tabindex="0" ref="tankArea"
                 @keydown.right="startMoveRight"
                 @keyup.right="stopMove"

                 @keydown.left="startMoveLeft"
                 @keyup.left="stopMove"

                 @keydown.up="startMoveUp"
                 @keyup.up="stopMove"

                 @keydown.down="startMoveDown"
                 @keyup.down="stopMove"

                 @keydown.space="shoot"
                 :style = tankAreaStyle>
                <!--<div v-for="tank in tanks" :class="tank.class" :style = "'top:' + tank.top + 'rem; left:' + tank.left + 'rem'">-->
                <!--</div>-->
                <div v-for="(tank,index) in tankMap" :key="index" :class="tank[1].campClass+tank[1].direcClass" :style = "'top:' + tank[1].top + 'rem; left:' + tank[1].left + 'rem'">
                </div>
                <div v-for="cloud in clouds" class="cloud" :style = "'top:' + cloud.top + 'rem; left:' + cloud.left + 'rem'" ></div>
                <div v-for="bullet in bullets" :class="bullet.class" :style = "'top:' + bullet.top + 'rem; left:' + bullet.left + 'rem'">
                </div>
                <Explosion v-for="explosion in explosions" @removeExplosion="removeExplosion"
                           :style = "'top:' + explosion.top + 'rem; left:' + explosion.left + 'rem'" :id="explosion.id">
                </Explosion>
            </div>
        </el-col>
    </el-row>
    <audio style="display: none" src='/tank/audio/explode.wav' ref="explode" preload="auto"></audio>
    <audio style="display: none" src='/tank/audio/tank_fire.wav' ref="tankFire" preload="auto"></audio>
    <audio style="display: none" src='/tank/audio/tank_move.wav' ref="tankMove" loop  preload="auto"></audio>
    <audio style="display: none" src='/tank/audio/startGame.mp3' ref="startAudio"  preload="auto"></audio>
</template>

<script setup>

    import Explosion from '@/components/recreation/tank/Explosion.vue'
    import request from '@/utils/request.js'
    import Tank from './tank.js'
    import { ElMessage } from 'element-plus'
    import {ref, reactive, onMounted,nextTick,computed} from 'vue'
    let explode = ref(null)
    let tankFire = ref(null)
    let tankMove = ref(null)
    let startAudio = ref(null)

    let ENEMY = 'enemy'
    let OUR = 'our'
    let tankMap = reactive(new Map());

    let bullets = reactive([]);
    let explosions = reactive([]);
    let clouds = reactive([]);
    let tankSize = 4

    let maxHeight = ref(35)
    let maxWidth = ref(55)

    let MYTANK = "tank"
    let BADTANK = "tankBad"
    let armynum = ref(1)
    let tankArea = ref(null)

    let tankSpeed = 0.8
    let bulletSpeed = 1.5
    let bulletsInterval = null
    let tanksInterval = null
    let tankAreaStyle = computed(()=>{
        return "width:"+maxWidth.value +"rem;height:"+maxHeight.value+"rem"
    })

    onMounted(() => {
    })

    function initBulletsInterval(){
         bulletsInterval = setInterval(function () {
             for (let i = bullets.length -1 ; i >= 0; i--) {
                 let bullet = bullets[i]
                 let direction = bullet.direction
                 if(direction=='left'){
                     bullet.left =  bullet.left - bulletSpeed
                     if(bullet.left <= -0.75 || isHitTank(bullet)){
                         bullets.splice(i,1)
                     }
                 }else if(direction=='right'){
                     bullet.left =  bullet.left + bulletSpeed
                     if(bullet.left >= maxWidth.value || isHitTank(bullet)){
                         bullets.splice(i,1)
                     }

                 }else if(direction=='up'){
                     bullet.top = bullet.top - bulletSpeed
                     if(bullet.top <= -0.75 || isHitTank(bullet)){
                         bullets.splice(i,1)
                     }
                 }else if(direction=='down'){
                     bullet.top = bullet.top + bulletSpeed
                     if(bullet.top >= maxHeight.value || isHitTank(bullet)){
                         bullets.splice(i,1)
                     }
                 }
             }
        },50)
    }

    function initTanksInterval(){
        tanksInterval = setInterval(function () {
            if(tankMap.size == 1 && tankMap.get("my")){
                ElMessage.success("游戏获胜")
                clearInterval(tanksInterval)
            }
            for (let [key, tank] of tankMap) {
                if(tank.moving){
                    if(tank.direction == 'right'){
                        if(tank.left >= maxWidth.value - tankSize){
                            tank.left = maxWidth.value - tankSize
                        }else {
                            tank.left = tank.left + tankSpeed
                        }
                    }else if(tank.direction == 'up'){
                        if(tank.top <= 0){
                            tank.top = 0
                        }else {
                            tank.top = tank.top - tankSpeed
                        }
                    }else if( tank.direction == 'left'){
                        if(tank.left <= 0){
                            tank.left = 0
                        }else{
                            tank.left = tank.left - tankSpeed
                        }
                    }else if( tank.direction == 'down'){
                        if(tank.top >= maxHeight.value - tankSize){
                            tank.top = maxHeight.value - tankSize
                        }else{
                            tank.top = tank.top + tankSpeed
                        }
                    }
                }
            }
        },50)
    }

    function isHitTank(bullet){
        for (let [key, val] of tankMap) {
            let tank =  val
            // if(tank.type == OUR){
            //     continue
            // }
            if(tank.camp == bullet.camp){
                continue
            }
            if((bullet.top > tank.top) && (bullet.left >tank.left) && (bullet.top < tank.top + tankSize) && (bullet.left < tank.left + tankSize)){
                tank.die()
                tankMap.delete(key)
                if(tank.camp=="mine"){
                    ElMessage.error("游戏失败")
                }
                explode.value.play()
                let num = new Date().getTime()
                explosions.push({top:tank.top, left:tank.left, id:num})
                return true
            }
        }
    }

    function shoot(){
        let tank = tankMap.get("my")
        if(!tank){return}
        let bullet = tank.shoot()
        bullets.push(bullet)
    }

    function startMoveRight(){
        let tank = tankMap.get("my")
        if(!tank){return}
        tank.startMoveRight()
    }

    function startMoveLeft(){
        let tank = tankMap.get("my")
        if(!tank){return}
        tank.startMoveLeft()
    }


    function startMoveUp(){
        let tank = tankMap.get("my")
        if(!tank){return}
        tank.startMoveUp()
    }

    function startMoveDown(i){
        let tank = tankMap.get("my")
        if(!tank){return}
        tank.startMoveDown()
    }

    function stopMove(){
        let tank = tankMap.get("my")
        if(!tank){return}
        tank.stopMove()
    }

    function removeExplosion(id){

        for (let i = explosions.length - 1; i >=0 ; i--) {
            let explosion = explosions[i]
            if(explosion.id == id){
                explosions.splice(i,1)
                break
            }
        }
    }

    function startGame(){

        if(bulletsInterval){
            ElMessage.error("游戏正在进行")
            return
        }
        stopGame()
        let tank = new Tank(0, 0, MYTANK, tankMove, tankFire, "mine")
        tankMap.set("my",(tank));

        for (let i = 0; i < armynum.value; i++) {
            let top = Math.round((maxHeight.value - tankSize) * Math.random())
            let left = Math.round((maxWidth.value - tankSize) * Math.random())
            let tank1 = new Tank(top, left, BADTANK, tankMove, tankFire, "others")
            tankMap.set("my" + i, (tank1));
        }

        for (let i = 0; i < 10; i++) {

            let top = Math.round(maxHeight.value * Math.random())
            let left = Math.round(maxWidth.value * Math.random())
            let ran = Math.round(20 * Math.random())
            for (let j = 0; j < ran; j++) {
                if(i%3==0){
                    top = top + tankSize
                    clouds.push({top: top, left: left})
                }
                if(i%3==1){
                    left = left + tankSize
                    clouds.push({top: top, left: left})
                }
                if(i%3==2){
                    top = top - tankSize
                    clouds.push({top: top, left: left})
                }
                if(i%3==3){
                    left = left - tankSize
                    clouds.push({top: top, left: left})
                }
            }
        }

        initTanksInterval()
        initBulletsInterval()
        initArmy()

        tankArea.value.focus()
        // startAudio.value.play()
    }

    function stopGame(){
        clouds.splice(0, clouds.length)
        bullets.splice(0, bullets.length)
        clearInterval(tanksInterval)
        tanksInterval = null

        clearInterval(bulletsInterval)
        bulletsInterval = null

        clearInterval(armyMove)
        armyMove = null

        for (let [key, val] of tankMap) {
            tankMap.delete(key)
        }

        startAudio.value.currentTime = 0
        startAudio.value.pause()
    }
    let armyMove = null

function initArmy() {
    let armyInterval = 400
    armyMove = setInterval(function () {
        armyInterval = armyInterval +(500 * (Math.random()))
        for (let [key, tank] of tankMap) {

            let bulletDelay = Math.round(armyInterval * (Math.random()))
            let r = Math.round(4 * (Math.random()))
            let b = Math.round(4 * (Math.random()))
            if(key == 'my'){continue}
            tank.stopMove()
            if(r==0){
                tank.startMoveDown()
            }else if(r==1){
                tank.startMoveUp()
            }else if(r==2){
                tank.startMoveRight()
            }else if(r==3){
                tank.startMoveLeft()
            }
            if(r == b){
                setTimeout(function () {
                    if(tanksInterval && tank.alive){
                        let bullet = tank.shoot()
                        bullets.push(bullet)
                    }
                }, bulletDelay)
            }

        }
    }, armyInterval)
}
</script>
<style lang="css" scoped>
    .address {overflow:hidden;white-space:nowrap;word-wrap:break-word;text-overflow:"ellipsis";}
    .head {background-color: #9561cc}
    [v-cloak]{
        display: none  !important;
    }
    .demo-form-inline{
        display: flex !important;
        justify-content: flex-start !important;
        align-items: center !important;
    }
    .tank{
        position:absolute;
        width: 4rem;
        height: 4rem;
        background-image: url('../../assets/tank/GoodTank1.png');
        background-size: cover
    }
    .cloud{
        position:absolute;
        width: 4rem;
        height: 4rem;
        background-color: #ccc;
        z-index: 10;
    }
    .tankBad{
        position:absolute;
        width: 4rem;
        height: 4rem;
        background-image: url('../../assets/tank/tank_.png');
        background-size:cover;
    }
    .bulletRight{
        position:absolute;
        width: 1.5rem;
        height: .5rem;
        background-image: url('../../assets/tank/bulletR.png');
        background-size: cover
    }
    .bulletLeft{
        position:absolute;
        width: 1.5rem;
        height: .5rem;
        background-image: url('../../assets/tank/bulletL.png');
        background-size: cover
    }
    .bulletUp{
        position:absolute;
        width: .5rem;
        height: 1.5rem;
        background-image: url('../../assets/tank/bulletU.png');
        background-size: cover
    }
    .bulletDown{
        position:absolute;
        width: .5rem;
        height: 1.5rem;
        background-image: url('../../assets/tank/bulletD.png');
        background-size: cover
    }

    .turnDown{
        transform : rotate(180deg)
    }

    .turnUp{
        transform : rotate(0deg)
    }

    .turnLeft{
        transform : rotate(270deg)
    }

    .turnRight{
        transform : rotate(90deg)
    }

    .tankArea{
        background-color: #cbdcff;
        overflow: hidden;
        border-radius: 5px;
        position: relative;
        outline-offset: -1px;
    }

    .tankArea:focus{
        outline: none;
        box-shadow: 0 0 0 1px #7081ff, 0 0 0 2px white, 0 0 0 3px #7081ff;
    }
    </style>